package com.xuzimian.global.demo.spring.security.oauth2.client.config;

import com.xuzimian.global.demo.spring.security.oauth2.client.filter.QQAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutFilter;

/**
 * 如果是使用本地oauth server登录授权需要先启动 spring-security-oauth2-server 程序，保证
 * 能获取到keystire 加密证书。
 *
 * @program: global-demo
 * @description:
 * @author: xzm
 * @create: 2019-06-21 17:03
 **/
@Order(4)
@EnableWebSecurity
@EnableOAuth2Client
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("myloginFilter")
    private OAuth2ClientAuthenticationProcessingFilter myloginFilter;

    @Autowired
    @Qualifier("githubFilter")
    private OAuth2ClientAuthenticationProcessingFilter githubFilter;
    @Autowired
    @Qualifier("qqFilter")
    private QQAuthenticationFilter qqFilter;

    /**
     * 注意:anyRequest().authenticated() 应当放在所有匹配规则最后
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //定义站点权限(从Oauth2认证服务器来获取授权）
        http.antMatcher("/**").authorizeRequests()
                .antMatchers("/error", "/deny").permitAll()
                .anyRequest().authenticated()
                .and().logout().logoutUrl("/logout").permitAll()
                .and().csrf().disable();
        //设置oauth登陆
        setOauthLogin(http);

//        http.oauth2Login()
//                //.loginPage("/login")
//                .authorizationEndpoint()
//                .baseUri("http://localhost:8080")
//                .authorizationRequestResolver(getOAuth2AuthorizationRequestResolver());

    }

    private void setOauthLogin(HttpSecurity http) throws Exception {
        setMyOauthLogin(http);
        setGithubOauthLogin(http);
        setQQOauthLogin(http);
    }

    /**
     * 配置自定义的oauth2 授权服务 拦截地址。且配置了全局未授权错误重定向地址，
     * 所以，访问任何需要授权的地址，都会自动跳转该地址上，然后被myloginFilter
     * 拦截，引导到自定义授权服务上进行登录授权。
     *
     * @param http
     * @throws Exception
     */
    private void setMyOauthLogin(HttpSecurity http) throws Exception {
        http.addFilterBefore(myloginFilter, LogoutFilter.class);
        //此处配置了全局未授权错误重定向地址
        http.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
    }

    /**
     * 配置Github的oauth2 授权服务 拦截地址
     *
     * @param http
     */
    private void setGithubOauthLogin(HttpSecurity http) {
        http.addFilterBefore(githubFilter, LogoutFilter.class);
    }

    /**
     * 配置qq的oauth2 授权服务 拦截地址
     *
     * @param http
     */
    private void setQQOauthLogin(HttpSecurity http) {
        http.addFilterBefore(qqFilter, LogoutFilter.class);
    }

}
